package com.explorex.infra.puma.gateway.netty.common;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @author: JacceYang
 * @createTime: 2022/10/12 20:29
 * @description:
 */
public class UserSocketSession {

    private final Map<Integer, List<BaseSocketSession>> userSockets;
    private final String userId;
    private final String domain;

    public UserSocketSession(String domain, String userId) {
        this.userId = userId;
        this.domain = domain;
        this.userSockets = new ConcurrentHashMap<>(2);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        UserSocketSession that = (UserSocketSession) o;
        return userId.equals(that.userId) && domain.equals(that.domain);
    }

    @Override
    public int hashCode() {
        return Objects.hash(userId, domain);
    }

    public boolean isEmpty() {
        if (userSockets == null || userSockets.isEmpty()) {
            return true;
        }
        return !userSockets.values().stream().filter(ele -> ele.size() > 0).findAny().isPresent();
    }

    public List<BaseSocketSession> getUserSocketList() {
        List<BaseSocketSession> result = new ArrayList<>();
        Collection<List<BaseSocketSession>> values = userSockets.values();
        values.stream().forEach(ele -> result.addAll(ele));
        return result;
    }

    public List<BaseSocketSession> getUserSockets(Integer terminal) {
        return userSockets.get(terminal);
    }

    public void addSocket(Integer terminal, BaseSocketSession session) {
        if (session == null) {
            return;
        }

        List<BaseSocketSession> orDefault = userSockets.getOrDefault(terminal, new CopyOnWriteArrayList<>());
        // old 加过一边不要再加了
        if (orDefault.contains(session)) {
            return;
        }

        orDefault.add(session);
        userSockets.put(terminal, orDefault);
    }

    public void removeSocket(BaseSocketSession session) {
        for (List<BaseSocketSession> baseSocketSessions : userSockets.values()) {
            baseSocketSessions.remove(session);
        }
    }

    @Override
    public String toString() {
        return "UserSocketSession{" +
                "userSockets=" + userSockets +
                ", userId='" + userId + '\'' +
                ", domain='" + domain + '\'' +
                '}';
    }
}
